#include "Builder.h"

Builder::Builder()
	:QObject()
{
	qDebug() << "Info : start Builder...";
	ID_CurrentFile = 0;
}

Builder::~Builder()
{
	qDebug() << "Info :  stop Builder...";
}
void Builder::setPathXML(QString xmlPath)
{
	QFileInfo FI_Path;
	FI_Path.setFile(xmlPath);
	XML_Path = FI_Path.path();
}

void Builder::setPathUpdater(QString updaterPath)
{
	Updater_Path = updaterPath;
}
void Builder::setLists(QList<UpdateFile*> Files)
{
	ListTocreateXML = Files;
	CreateAndConfigureListXML();
}
void Builder::CreateAndConfigureListXML()
{
	QString Sha1OldFiles;
	for(int i=0; i<ListTocreateXML.size();i++)
	{
		if((ListTocreateXML[i]->getSha1()).isEmpty())
		{
			#ifdef QT_DEBUG
				#ifdef ENABLE_DEBUG_LISTFILE_CREATEXML
					qDebug() << ListTocreateXML[i]->getPath() + "/" + ListTocreateXML[i]->getFilename();
				#endif 
			#endif
			ListTocreateXML[i]->setSha1(CalcSha1(ListTocreateXML[i]->getPath() + "/" + ListTocreateXML[i]->getFilename()));
			ListToUpdate.append(ListTocreateXML[i]);
		}
		else
		{
			//Tester mises a jour anciens fichiers
			Sha1OldFiles = CalcSha1(XML_Path + "/" + ListTocreateXML[i]->getPath() + "/"+ ListTocreateXML[i]->getFilename());
			if(Sha1OldFiles == ListTocreateXML[i]->getSha1())
			{
				//Pas besoin de mettre à jour
				//TODO : Rajouter une option de Forcage
			}
			else
			{
				//TODO : fichiers pas pareils
				if(Sha1OldFiles == "ERR")
				{//Fichier inexistant)}
					//Si on demande au cas par cas
						qWarning() << "Fichier inexistant :" << XML_Path + "/" + ListTocreateXML[i]->getPath() + "/"+ ListTocreateXML[i]->getFilename();
						//Si on conserve dans la liste
						
						//Si on supprime de la liste
							//[Defaut]
				}
				else //Ancien fichier toujours présent dont le Sha1 à changé
				{
					ListTocreateXML[i]->setSha1(Sha1OldFiles);
					ListToUpdate.append(ListTocreateXML[i]); //On force la MAJ
				} 
			}
		}
	}
	#ifdef QT_DEBUG
		Debug_ShowLists();
	#endif
}
QString Builder::CalcSha1(QString Path)
{
	QFile FileToHash(Path);
	QByteArray ba;
	// Tu crées ton QCryptographicHash
	QCryptographicHash CPU(QCryptographicHash::Sha1);
	if (FileToHash.open(QIODevice::ReadOnly))
	{
		while (!FileToHash.atEnd())
		{
			ba = FileToHash.read(1024);
			// Faire ici l'ajout des données à ton QCryptographicHash
			CPU.addData(ba);
		}
		FileToHash.close();
		// Tu demandes le résultat du hash
		ba = CPU.result();
		QString HashOutput(ba.toHex());
		return HashOutput;
	}
	else
	{
		//Problème lecture fichier
		QString HashOutput("ERR");
		//QMessageBox::information(0, QObject::trUtf8("Sha1"),
        //                        QObject::trUtf8("Impossible de claculer le Hash du fichier" + Path));
		return HashOutput;
	}
}

void Builder::Debug_ShowLists()
{
	#ifdef ENABLE_DEBUG_SHOWLISTS
		int i;
		qDebug() << "Start debug in :" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__;
		qDebug() << "----------------------------------------------------"
				 << "   All Files   "
				 << "----------------------------------------------------";
		for(i=0; i<ListTocreateXML.size();i++)
		{
			qDebug() << ListTocreateXML[i]->getFilename() << "|"
					 << ListTocreateXML[i]->getpriority()<< "|"
					 << ListTocreateXML[i]->getPath()<< "|"
					 << ListTocreateXML[i]->getSha1() ;
		}
		qDebug() << "----------------------------------------------------"
				 << "   Files to Hash and Create archive   "
				 << "----------------------------------------------------";
		for(i=0; i<ListToUpdate.size();i++)
		{
			qDebug() << ListToUpdate[i]->getFilename() << "|"
					 << ListToUpdate[i]->getpriority()<< "|"
					 << ListToUpdate[i]->getPath()<< "|"
					 << ListToUpdate[i]->getSha1() ;
		}
		qDebug() << "End debug in :" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__;
	#endif
}

QList<UpdateFile*>  Builder::getXMLList()
{
	return ListTocreateXML;
}

void Builder::Build()
{
	QDir TstDir;
	Archiver = new InterfaceArchiver();
	connect(Archiver, SIGNAL(ArchiveCreateEnd(QString, bool)), this, SLOT(BuildNextFile(QString, bool)));
	QString TstPath;
	//Pour chaque fichier
	for(int i=0; i<ListTocreateXML.size();i++)
	{
		TstPath = ListTocreateXML[i]->getPath();
		TstPath = TstPath.remove(Updater_Path);
		TstDir.setPath(XML_Path + TstPath);
		//si dossier n'existe pas
		if(!TstDir.exists())
		{//créer dossier
			#ifdef QT_DEBUG
				qDebug() << "Folder" << TstDir.path() << "dont exist!";
			#endif
			if(!TstDir.mkpath(TstDir.path()))
			{	
				qDebug() << "Failled to create path :" << TstDir.path();
				delete Archiver;
				emit CanYouShowErrorMsg("Impossible de créer le chemin : " + TstDir.path());
				return;
			}
		}
		//Si archive existe
		if(!Archiver->CheckAndDeleteOldArchive(TstDir.path() + ListTocreateXML[i]->getFilename()))
		{
			emit CanYouShowErrorMsg("Impossible de supprimer le fichier : " + TstDir.path() + ListTocreateXML[i]->getFilename());
			return;
		}
	}
	ID_CurrentFile = 0;
	BuildNextFile();
}
void Builder::BuildNextFile(QString OutputFilePath, bool ExitStatut)
{
	emit CanYouShowProgress(ID_CurrentFile + 1, ListTocreateXML.size());
	if(!ExitStatut)
	{
		//on arrète tout
		qDebug() << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__
				 << "=> Error :" << "BuildNextFile(), !ExitStatut :" << ListTocreateXML[ID_CurrentFile - 1]->getFilename();
		emit CanYouShowErrorMsg("Impossible de créer l'archive : " + OutputFilePath);
		delete Archiver;
	}
	if(ID_CurrentFile < ListTocreateXML.size())
	{
		//Archiver->CreateArchive(QString InputFilePath,QString OutputFilePath);
		ID_CurrentFile++;
		QString CreatePath;
		CreatePath = ListTocreateXML[ID_CurrentFile - 1]->getPath();
		CreatePath = CreatePath.remove(Updater_Path);
		Archiver->CreateArchive(ListTocreateXML[ID_CurrentFile - 1]->getPath() + "/" + ListTocreateXML[ID_CurrentFile - 1]->getFilename(),XML_Path + CreatePath + "/" + ListTocreateXML[ID_CurrentFile - 1]->getFilename());
	}
	else
	{
		emit CanYouShowMsg("Génération réussie de " + QString::number(ListTocreateXML.size() - 1) + " fichiers");
		delete Archiver;
		//Archivage fini avec succès!!!
	}
	return;
}